package com.yochi.pictureseditor.effects.effectsimpl;

import com.yochi.pictureseditor.effects.Effect;
import com.yochi.pictureseditor.effects.EffectEnum;
import com.yochi.pictureseditor.effects.filters.FilterEnum;
import com.yochi.pictureseditor.exceptions.NullImageException;
import com.yochi.pictureseditor.factories.EffectFactory;
import com.yochi.pictureseditor.images.Image;
import com.yochi.pictureseditor.images.ImageImpl;

public class EffectSobel extends Effect {
	
	  /////////////////
	 // CONSTRUCTOR //
	/////////////////
	
	public EffectSobel(Image img) {
		super(img);
	}
	
	  ////////////
	 // PUBLIC //
	/////////////
	
	@Override
	public Image apply() throws NullImageException {
		if(getImage()==null) throw new NullImageException("load an image before applying effect");
		Image result = new ImageImpl(getImage().getProfondeur(), getImage().getLargeur(), getImage().getHauteur());
		
		result = new EffectFactory().buildEffect(EffectEnum.BLACKANDWHITE, getImage()).apply();
		Image result1 = new EffectFactory().buildEffect(FilterEnum.SOBEL1, result).apply();
		Image result2 = new EffectFactory().buildEffect(FilterEnum.SOBEL2, result).apply();
		int newPixelValue;
		for(int p=0; p<result.getProfondeur(); p++) {
			for(int l=1; l<result.getLargeur()-1; l++) {
				for(int h=1; h<result.getHauteur()-1; h++) {
					if((getImage().getProfondeur()==4 && p<3) || (getImage().getProfondeur()==2 && p<1)) {
						newPixelValue = Double.valueOf(Math.sqrt(Math.pow(result1.getPixel(p, l, h), 2)+Math.pow(result2.getPixel(p, l, h), 2))).intValue();
						if(newPixelValue>255) {
							newPixelValue = 255;
						} else if(newPixelValue<0) {
							newPixelValue = 0;
						}
					} else { // alpha canal
						newPixelValue = getImage().getPixel(p, l, h);
					}
					result.setPixel(p, l, h, (char) newPixelValue);
		}   }   }
		// gestion des bords 
		for(int p=0; p<getImage().getProfondeur(); p++) {
			for(int h=0; h<getImage().getHauteur(); h++) {
				result.setPixel(p, 0, h, result.getPixel(p, 1, h));
				result.setPixel(p, result.getLargeur()-1, h, result.getPixel(p, result.getLargeur()-2, h));
			}
			for(int l=0; l<getImage().getLargeur(); l++) {
				result.setPixel(p, l, 0, result.getPixel(p, l, 1));
				result.setPixel(p, l, result.getHauteur()-1, result.getPixel(p, l, result.getHauteur()-2));
			}
		}
		setResult(result);
		
		return result;
	}
	
	@Override
	public String toString() {
		return "[EffectSobel]";
	}

}
